জাভাস্ক্রিপ্টে রেফারেন্স (Reference) একটি ভ্যালু বা অবজেক্টের নির্দেশক (pointer) হিসেবে কাজ করে। যখন কোনো ভেরিয়েবল বা অবজেক্টের রেফারেন্স ব্যবহার করা হয়, তখন সেটি আসলে সেই অবজেক্টের অবস্থান বা স্মৃতি ঠিকানা (memory address) নির্দেশ করে, যার মাধ্যমে আপনি ঐ অবজেক্টের মান বা ভ্যালু অ্যাক্সেস করতে পারেন।
জাভাস্ক্রিপ্টে ডেটা টাইপগুলোকে মূলত দুটি শ্রেণীতে ভাগ করা হয়: প্রিমিটিভ টাইপ (Primitive Type) এবং রেফারেন্স টাইপ (Reference Type)।
প্রিমিটিভ টাইপের ভেরিয়েবলগুলো সরাসরি ভ্যালু সংরক্ষণ করে এবং এদের মধ্যে রেফারেন্স ব্যবহার হয় না। এই টাইপগুলো অন্তর্ভুক্ত:
String
(স্ট্রিং)Number
(সংখ্যা)Boolean
(বুলিয়ান)Null
(নাল)Undefined
(অপরিবর্তিত)Symbol
(সিম্বল)রেফারেন্স টাইপের ভেরিয়েবলগুলো মূলত একটি অবজেক্টের রেফারেন্স (অথবা স্মৃতি ঠিকানা) ধারণ করে। এগুলোর মধ্যে রয়েছে:
Object
(অবজেক্ট)Array
(অ্যারেআই)Function
(ফাংশন)Date
(তারিখ)RegExp
(রেগুলার এক্সপ্রেশন)এগুলোর মধ্যে একটির মান পরিবর্তন করলে, তা সমস্ত রেফারেন্সে প্রভাব ফেলে।
রেফারেন্স টাইপের ভেরিয়েবল যখন কোনো অবজেক্টের সাথে কাজ করে, তখন মূলত রেফারেন্স (pointer) কপি করা হয়, অর্থাৎ আসল ডেটা কপি হয় না। যদি একটি অবজেক্টের মান পরিবর্তন করা হয়, তবে তা সমস্ত রেফারেন্সে প্রতিফলিত হয়।
let obj1 = { name: "John" };
let obj2 = obj1; // obj2 এখন obj1 এর রেফারেন্স ধারণ করছে
obj2.name = "Doe"; // obj2 এর name মান পরিবর্তন
console.log(obj1.name); // আউটপুট: Doe
console.log(obj2.name); // আউটপুট: Doe
এখানে, obj2
এবং obj1
একই অবজেক্টের রেফারেন্স ধারণ করছে, তাই যখন obj2.name
পরিবর্তন করা হয়, তখন obj1.name
-ও পরিবর্তিত হয়।
প্রিমিটিভ টাইপের ভেরিয়েবলগুলির ক্ষেত্রে, যখন একটি ভেরিয়েবল অন্য একটি ভেরিয়েবলে কপি করা হয়, তখন আসল মান কপি হয় এবং কোন রেফারেন্স শেয়ার হয় না।
let a = 10;
let b = a; // b এ a এর মান কপি হবে
b = 20; // b এর মান পরিবর্তন
console.log(a); // আউটপুট: 10 (a এর মান অপরিবর্তিত)
console.log(b); // আউটপুট: 20
এখানে a
এবং b
আলাদা ভেরিয়েবল, তাদের মধ্যে রেফারেন্স শেয়ার হয়নি, বরং a
এর মান b
তে কপি হয়েছে।
রেফারেন্স টাইপের ক্ষেত্রে, একটি অবজেক্টকে অন্য একটি ভেরিয়েবলে কপি করলে, আসলে রেফারেন্স কপি হয়। এর মানে হলো, দুটি ভেরিয়েবল একই অবজেক্টের রেফারেন্স শেয়ার করবে এবং একটির পরিবর্তন অন্যটির ওপরও প্রভাব ফেলবে।
let person = { name: "Alice", age: 25 };
let anotherPerson = person; // anotherPerson এখন person এর রেফারেন্স ধারণ করছে
anotherPerson.age = 30; // anotherPerson এর age পরিবর্তন
console.log(person.age); // আউটপুট: 30 (person এর age পরিবর্তিত)
console.log(anotherPerson.age); // আউটপুট: 30
এখানে, person
এবং anotherPerson
একই অবজেক্টের রেফারেন্স শেয়ার করছে, তাই anotherPerson
এর মান পরিবর্তিত হলে person
-এর মানও পরিবর্তিত হয়।
যদি আপনি একটি অবজেক্টের মান কপি করতে চান এবং তা অন্য কোনো অবজেক্টের সাথে সম্পর্কিত না হয়, তবে আপনাকে শ্যালো কপি (Shallow Copy) অথবা ডিপ কপি (Deep Copy) করতে হবে।
শ্যালো কপি করার জন্য Object.assign()
অথবা স্প্রেড অপারেটর (...
) ব্যবহার করা যায়। এটি শুধুমাত্র প্রথম স্তরের প্রপার্টি কপি করে, গভীর স্তরের অবজেক্ট কপি হয় না।
let person1 = { name: "John", address: { city: "New York", zip: "10001" } };
let person2 = Object.assign({}, person1); // শ্যালো কপি
person2.address.city = "Los Angeles"; // person2 এর address পরিবর্তন
console.log(person1.address.city); // আউটপুট: Los Angeles (person1 এর address-ও পরিবর্তিত)
console.log(person2.address.city); // আউটপুট: Los Angeles
এখানে, address
অবজেক্টের রেফারেন্স কপি হচ্ছে, তাই person1
এবং person2
একে অপরের address
অবজেক্ট শেয়ার করছে।
ডিপ কপি করার জন্য আপনি একটি নতুন অবজেক্ট তৈরি করতে পারেন, যেখানে একটি অবজেক্টের প্রতিটি স্তরের ভ্যালু কপি হয় এবং মূল অবজেক্টের সাথে কোনো সম্পর্ক থাকে না।
let person1 = { name: "John", address: { city: "New York", zip: "10001" } };
let person2 = JSON.parse(JSON.stringify(person1)); // ডিপ কপি
person2.address.city = "Los Angeles"; // person2 এর address পরিবর্তন
console.log(person1.address.city); // আউটপুট: New York (person1 এর address অপরিবর্তিত)
console.log(person2.address.city); // আউটপুট: Los Angeles
এখানে, JSON.parse(JSON.stringify())
পদ্ধতি দিয়ে একটি ডিপ কপি করা হয়েছে, যেখানে পুরো অবজেক্টটি নতুন করে কপি হয় এবং person1
এবং person2
এর মধ্যে কোনো সম্পর্ক থাকে না।
জাভাস্ক্রিপ্টে রেফারেন্স টাইপের ভেরিয়েবলগুলি একটি অবজেক্টের স্মৃতি ঠিকানা (memory address) ধারণ করে এবং যখন এগুলি অন্য ভেরিয়েবলে কপি করা হয়, তখন আসলে তাদের রেফারেন্স কপি হয়। এর ফলে, একটি ভেরিয়েবলের পরিবর্তন অন্য ভেরিয়েবলগুলোর ওপরও প্রভাব ফেলে। তবে প্রিমিটিভ টাইপের ক্ষেত্রে সরাসরি ভ্যালু কপি হয় এবং পরিবর্তন অন্য ভেরিয়েবলে প্রভাব ফেলে না। শ্যালো কপি এবং ডিপ কপি পদ্ধতি ব্যবহার করে, আমরা রেফারেন্স টাইপের ভেরিয়েবলগুলির মধ্যে সম্পর্ক নিয়ন্ত্রণ করতে পারি।
জাভাস্ক্রিপ্টে রেফারেন্স (Reference) একটি ভ্যালু বা অবজেক্টের নির্দেশক (pointer) হিসেবে কাজ করে। যখন কোনো ভেরিয়েবল বা অবজেক্টের রেফারেন্স ব্যবহার করা হয়, তখন সেটি আসলে সেই অবজেক্টের অবস্থান বা স্মৃতি ঠিকানা (memory address) নির্দেশ করে, যার মাধ্যমে আপনি ঐ অবজেক্টের মান বা ভ্যালু অ্যাক্সেস করতে পারেন।
জাভাস্ক্রিপ্টে ডেটা টাইপগুলোকে মূলত দুটি শ্রেণীতে ভাগ করা হয়: প্রিমিটিভ টাইপ (Primitive Type) এবং রেফারেন্স টাইপ (Reference Type)।
প্রিমিটিভ টাইপের ভেরিয়েবলগুলো সরাসরি ভ্যালু সংরক্ষণ করে এবং এদের মধ্যে রেফারেন্স ব্যবহার হয় না। এই টাইপগুলো অন্তর্ভুক্ত:
String
(স্ট্রিং)Number
(সংখ্যা)Boolean
(বুলিয়ান)Null
(নাল)Undefined
(অপরিবর্তিত)Symbol
(সিম্বল)রেফারেন্স টাইপের ভেরিয়েবলগুলো মূলত একটি অবজেক্টের রেফারেন্স (অথবা স্মৃতি ঠিকানা) ধারণ করে। এগুলোর মধ্যে রয়েছে:
Object
(অবজেক্ট)Array
(অ্যারেআই)Function
(ফাংশন)Date
(তারিখ)RegExp
(রেগুলার এক্সপ্রেশন)এগুলোর মধ্যে একটির মান পরিবর্তন করলে, তা সমস্ত রেফারেন্সে প্রভাব ফেলে।
রেফারেন্স টাইপের ভেরিয়েবল যখন কোনো অবজেক্টের সাথে কাজ করে, তখন মূলত রেফারেন্স (pointer) কপি করা হয়, অর্থাৎ আসল ডেটা কপি হয় না। যদি একটি অবজেক্টের মান পরিবর্তন করা হয়, তবে তা সমস্ত রেফারেন্সে প্রতিফলিত হয়।
let obj1 = { name: "John" };
let obj2 = obj1; // obj2 এখন obj1 এর রেফারেন্স ধারণ করছে
obj2.name = "Doe"; // obj2 এর name মান পরিবর্তন
console.log(obj1.name); // আউটপুট: Doe
console.log(obj2.name); // আউটপুট: Doe
এখানে, obj2
এবং obj1
একই অবজেক্টের রেফারেন্স ধারণ করছে, তাই যখন obj2.name
পরিবর্তন করা হয়, তখন obj1.name
-ও পরিবর্তিত হয়।
প্রিমিটিভ টাইপের ভেরিয়েবলগুলির ক্ষেত্রে, যখন একটি ভেরিয়েবল অন্য একটি ভেরিয়েবলে কপি করা হয়, তখন আসল মান কপি হয় এবং কোন রেফারেন্স শেয়ার হয় না।
let a = 10;
let b = a; // b এ a এর মান কপি হবে
b = 20; // b এর মান পরিবর্তন
console.log(a); // আউটপুট: 10 (a এর মান অপরিবর্তিত)
console.log(b); // আউটপুট: 20
এখানে a
এবং b
আলাদা ভেরিয়েবল, তাদের মধ্যে রেফারেন্স শেয়ার হয়নি, বরং a
এর মান b
তে কপি হয়েছে।
রেফারেন্স টাইপের ক্ষেত্রে, একটি অবজেক্টকে অন্য একটি ভেরিয়েবলে কপি করলে, আসলে রেফারেন্স কপি হয়। এর মানে হলো, দুটি ভেরিয়েবল একই অবজেক্টের রেফারেন্স শেয়ার করবে এবং একটির পরিবর্তন অন্যটির ওপরও প্রভাব ফেলবে।
let person = { name: "Alice", age: 25 };
let anotherPerson = person; // anotherPerson এখন person এর রেফারেন্স ধারণ করছে
anotherPerson.age = 30; // anotherPerson এর age পরিবর্তন
console.log(person.age); // আউটপুট: 30 (person এর age পরিবর্তিত)
console.log(anotherPerson.age); // আউটপুট: 30
এখানে, person
এবং anotherPerson
একই অবজেক্টের রেফারেন্স শেয়ার করছে, তাই anotherPerson
এর মান পরিবর্তিত হলে person
-এর মানও পরিবর্তিত হয়।
যদি আপনি একটি অবজেক্টের মান কপি করতে চান এবং তা অন্য কোনো অবজেক্টের সাথে সম্পর্কিত না হয়, তবে আপনাকে শ্যালো কপি (Shallow Copy) অথবা ডিপ কপি (Deep Copy) করতে হবে।
শ্যালো কপি করার জন্য Object.assign()
অথবা স্প্রেড অপারেটর (...
) ব্যবহার করা যায়। এটি শুধুমাত্র প্রথম স্তরের প্রপার্টি কপি করে, গভীর স্তরের অবজেক্ট কপি হয় না।
let person1 = { name: "John", address: { city: "New York", zip: "10001" } };
let person2 = Object.assign({}, person1); // শ্যালো কপি
person2.address.city = "Los Angeles"; // person2 এর address পরিবর্তন
console.log(person1.address.city); // আউটপুট: Los Angeles (person1 এর address-ও পরিবর্তিত)
console.log(person2.address.city); // আউটপুট: Los Angeles
এখানে, address
অবজেক্টের রেফারেন্স কপি হচ্ছে, তাই person1
এবং person2
একে অপরের address
অবজেক্ট শেয়ার করছে।
ডিপ কপি করার জন্য আপনি একটি নতুন অবজেক্ট তৈরি করতে পারেন, যেখানে একটি অবজেক্টের প্রতিটি স্তরের ভ্যালু কপি হয় এবং মূল অবজেক্টের সাথে কোনো সম্পর্ক থাকে না।
let person1 = { name: "John", address: { city: "New York", zip: "10001" } };
let person2 = JSON.parse(JSON.stringify(person1)); // ডিপ কপি
person2.address.city = "Los Angeles"; // person2 এর address পরিবর্তন
console.log(person1.address.city); // আউটপুট: New York (person1 এর address অপরিবর্তিত)
console.log(person2.address.city); // আউটপুট: Los Angeles
এখানে, JSON.parse(JSON.stringify())
পদ্ধতি দিয়ে একটি ডিপ কপি করা হয়েছে, যেখানে পুরো অবজেক্টটি নতুন করে কপি হয় এবং person1
এবং person2
এর মধ্যে কোনো সম্পর্ক থাকে না।
জাভাস্ক্রিপ্টে রেফারেন্স টাইপের ভেরিয়েবলগুলি একটি অবজেক্টের স্মৃতি ঠিকানা (memory address) ধারণ করে এবং যখন এগুলি অন্য ভেরিয়েবলে কপি করা হয়, তখন আসলে তাদের রেফারেন্স কপি হয়। এর ফলে, একটি ভেরিয়েবলের পরিবর্তন অন্য ভেরিয়েবলগুলোর ওপরও প্রভাব ফেলে। তবে প্রিমিটিভ টাইপের ক্ষেত্রে সরাসরি ভ্যালু কপি হয় এবং পরিবর্তন অন্য ভেরিয়েবলে প্রভাব ফেলে না। শ্যালো কপি এবং ডিপ কপি পদ্ধতি ব্যবহার করে, আমরা রেফারেন্স টাইপের ভেরিয়েবলগুলির মধ্যে সম্পর্ক নিয়ন্ত্রণ করতে পারি।